home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / X11 / seyon / SeInit.c < prev    next >
C/C++ Source or Header  |  1995-05-03  |  18KB  |  541 lines

  1.  
  2. /*
  3.  * This file is part of the Seyon, Copyright (c) 1992-1993 by Muhammad M.
  4.  * Saggaf. All rights reserved.
  5.  *
  6.  * See the file COPYING (1-COPYING) or the manual page seyon(1) for a full
  7.  * statement of rights and permissions for this program.
  8.  */
  9.  
  10. #include <X11/Intrinsic.h>
  11. #include <X11/StringDefs.h>
  12. #include <X11/Shell.h>
  13. #include <X11/Xaw/Label.h>
  14. #include <X11/Xaw/Dialog.h>
  15. #include <signal.h>
  16. #include <fcntl.h>
  17.  
  18. #include "seyon.h"
  19. #include "SeDecl.h"
  20.  
  21. #ifndef HELPFILE
  22. #define HELPFILE "/usr/lib/X11/seyon.help"
  23. #endif
  24.  
  25. extern void     TopAbout(),
  26.                 TopHelp(),
  27.                 TopSet(),
  28.                 TopTransfer(),
  29.                 TopMisc(),
  30.                 SetNewlineTrMode(),
  31.                 FunMessage();
  32.  
  33. extern void     upload_acc_ok(),
  34.                 setVal_action_ok(),
  35.                 manual_dial_action_ok(),
  36.                 divert_action_ok();
  37.  
  38. extern Boolean  CvtStringToStringArray();
  39.  
  40. void            HangupConfirm(),
  41.                 ExecHangup(),
  42.                 ExitConfirm(),
  43.                 ExitAction(),
  44.                 test();
  45.  
  46. Boolean         inhibit_child = False;
  47. Widget          w_exit,
  48.                 w_kill,
  49.                 statusMessage;
  50. Widget          dialWidget, genericWidget;
  51. pid_t           w_child_pid = 0;
  52. Pixmap          progIcon;
  53.  
  54. #include "progIcon.h"
  55.  
  56. void
  57. InitVariables(topLevel)
  58.      Widget          topLevel;
  59. {
  60.   char            buffer[REG_BUF];
  61.  
  62.   sprintf(captureFile, "%s/%s", expand_fname(qres.defaultDirectory, buffer),
  63.       qres.captureFile);
  64.  
  65.   SetNewlineTrMode(qres.newlineTranslation);
  66. }
  67.  
  68. void
  69. SetIcon(topLevelWidget)
  70.      Widget          topLevelWidget;
  71. {
  72.   progIcon = 
  73.     XCreateBitmapFromData(XtDisplay(topLevelWidget),
  74.                           DefaultRootWindow(XtDisplay(topLevelWidget)),
  75.                           progIcon_bits, progIcon_width,
  76.                           progIcon_height);
  77.   XtVaSetValues(topLevelWidget, XtNiconPixmap, progIcon, NULL);
  78. }
  79.  
  80. void
  81. CreateCommandCenter()
  82. {
  83.   void            GetQuickKeyResources(),
  84.                   GetValueByPopupOKAction(),
  85.                   DispatchActionsCallback();
  86.   void            TopShell();
  87.   void            KillChildProc();
  88.  
  89.   Widget          mainBox,
  90.                   menuBox,
  91.                   statusBox,
  92.                   messageBox,
  93.                   quickKeyBox;
  94.   static Widget   status[NUM_MDM_STAT];
  95.   static Atom     wm_delete_window;
  96.   Dimension       menuBoxWidth;
  97.  
  98.   struct _quickKeyRes quickKeyRes;
  99.   Widget          quickKeyW;
  100.   char            qKBuf[REG_BUF];
  101.   int             i, n = 0;
  102.  
  103.   static XtActionsRec actionTable[] = {
  104.     {"UploadOk", upload_acc_ok},
  105.     {"SetValOk", setVal_action_ok},
  106.     {"ManualDialOk", manual_dial_action_ok},
  107.     {"DivertOk", divert_action_ok},
  108.     {"Exit", ExitAction},
  109.     {"GetValueByPopupOK", GetValueByPopupOKAction},
  110.   };
  111.  
  112.   XtAppAddActions(XtWidgetToApplicationContext(topLevel), actionTable, 
  113.                   XtNumber(actionTable));
  114.  
  115.   mainBox = SeAddPaned("mainBox", topLevel);
  116.   statusBox = AddBox("statusBox", mainBox);
  117.   messageBox = SeAddForm("messageBox", mainBox);
  118.   quickKeyBox = AddBox("quickKeyBox", mainBox);
  119.   menuBox = AddBox("menuBox", mainBox);
  120.  
  121.   status[0] = SeAddToggle("dcd", statusBox, NULL);
  122.   status[1] = SeAddToggle("dtr", statusBox, NULL);
  123.   status[2] = SeAddToggle("dsr", statusBox, NULL);
  124.   status[3] = SeAddToggle("rts", statusBox, NULL);
  125.   status[4] = SeAddToggle("cts", statusBox, NULL);
  126.   status[5] = SeAddToggle("rng", statusBox, NULL);
  127.  
  128.   statusMessage = SeAddLabel("message", messageBox);
  129.  
  130.   AddButton("about", menuBox, TopAbout, NULL);
  131.   AddButton("help", menuBox, TopHelp, NULL);
  132.   AddButton("set", menuBox, TopSet, NULL);
  133.   genericWidget = dialWidget = AddButton("dial", menuBox, TopDial, NULL);
  134.   AddButton("transfer", menuBox, TopTransfer, NULL);
  135.   AddButton("shellCommand", menuBox, TopShell, NULL);
  136.   AddButton("misc", menuBox, TopMisc, NULL);
  137.   AddButton("hangup", menuBox, HangupConfirm, NULL);
  138.   w_exit = AddButton("exit", menuBox, ExitConfirm, NULL);
  139.   w_kill = AddButton("kill", menuBox, KillChildProc, NULL);
  140.  
  141.   for (i = 0; i < MAX_SEQUICKKEYS; i++) {
  142.     sprintf(qKBuf, "quickKey%d", i+1);
  143.     GetQuickKeyResources(qKBuf, &quickKeyRes);
  144.     if (quickKeyRes.visible) {
  145.       n++;
  146.       quickKeyW = 
  147.         AddButton(qKBuf, quickKeyBox, DispatchActionsCallback, NULL);
  148.     }
  149.   }
  150.   if (n == 0) XtDestroyWidget(quickKeyBox);
  151.  
  152.   XtOverrideTranslations(topLevel,
  153.                     XtParseTranslationTable("<Message>WM_PROTOCOLS: Exit()"));
  154.  
  155.   /* Call UpdateStatusBox() before realizing the top-level widget so that
  156.      the status widget array in that function would be properly initialized
  157.      before the user is able to call hangup(), since the latter passes NULL
  158.      to UpdateStatusBox() */
  159.   UpdateStatusBox((XtPointer)status);
  160.  
  161.   XtSetMappedWhenManaged(topLevel, False);
  162.   XtRealizeWidget(topLevel);
  163.   XtVaGetValues(menuBox, XtNwidth, &menuBoxWidth, NULL);
  164.   XtVaSetValues(statusBox, XtNwidth, menuBoxWidth, NULL);
  165.   if (n) XtVaSetValues(quickKeyBox, XtNwidth, menuBoxWidth, NULL);
  166.  
  167.   /*
  168.    * (ideally one should not assume any fixed numbers, but this will do 
  169.    * for now).
  170.    *
  171.    * width of message box = label width
  172.    *                      + 2*border width (2*1)
  173.    *                      + defaultDistance (right) (1)
  174.    *                      + horizDistance (left) (4)
  175.    *
  176.    * desired width of label = width of menu box
  177.    *                        - hSpace of menu box (2*4) (to align with buttons)
  178.    *                        - border with of label (2*1)
  179.    *                        = width of menu box - 10
  180.    *
  181.    * => width of message box = width of menu box - 10 + 7
  182.    * => width of message box < width of menu box
  183.    * => menu box width is the controlling factor in deciding the widnow
  184.    *    width, as desired.
  185.    */
  186.   XtVaSetValues(statusMessage, XtNresizable, True, NULL);
  187.   XtVaSetValues(statusMessage, XtNwidth, menuBoxWidth - 10, NULL);
  188.   XtVaSetValues(statusMessage, XtNresizable, False, NULL);
  189.  
  190.   wm_delete_window = XInternAtom(XtDisplay(topLevel), 
  191.                                  "WM_DELETE_WINDOW", False);
  192.   XSetWMProtocols(XtDisplay(topLevel), XtWindow(topLevel), 
  193.                   &wm_delete_window, 1);
  194. }
  195.  
  196. void
  197. TopAbout(parent)
  198.      Widget          parent;
  199. {
  200.   Widget          popup,
  201.                   mBox,
  202.                   uBox,
  203.                   lBox,
  204.                   pic,
  205.                   msg,
  206.                   caption;
  207.   Pixmap          pix;
  208.   Dimension       width1,
  209.                   width2;
  210.   char            msgStr[LRG_BUF];
  211. #include "authPic.h"
  212.  
  213.   popup = SeAddPopup("about", parent);
  214.   mBox = SeAddPaned("mBox", popup);
  215.   uBox = SeAddBox("uBox", mBox);
  216.   lBox = SeAddBox("lBox", mBox);
  217.  
  218.   msg = SeAddLabel("msg", uBox);
  219.   pic = SeAddLabel("pic", uBox);
  220.   caption = SeAddLabel("caption", uBox);
  221.  
  222.   sprintf(msgStr, "%s %s rev. %s\n%s\n%s\n%s", "Seyon version", VERSION,
  223.       REVISION, "Copyright 1992-1993", "(c) Muhammad M. Saggaf",
  224.       "All rights reserved");
  225.   XtVaSetValues(msg, XtNlabel, msgStr, NULL);
  226.  
  227.   pix = XCreateBitmapFromData(XtDisplay(pic),
  228.                   DefaultRootWindow(XtDisplay(pic)),
  229.                   authPic_bits, authPic_width,
  230.                   authPic_height);
  231.   XtVaSetValues(pic, XtNbitmap, pix, NULL);
  232.  
  233.   width1 = SeWidgetWidth(msg);
  234.   width2 = SeWidgetWidth(pic);
  235.   width1 = width1 > width2 ? width1 : width2;
  236.   width2 = SeWidgetWidth(caption);
  237.   width1 = width1 > width2 ? width1 : width2;
  238.  
  239.   XtVaSetValues(msg, XtNwidth, width1, NULL);
  240.   XtVaSetValues(pic, XtNwidth, width1, NULL);
  241.   XtVaSetValues(caption, XtNwidth, width1, NULL);
  242.  
  243.   SeAddButton("dismiss", lBox, DestroyShell);
  244.  
  245.   XtPopupSpringLoaded(popup);
  246. }
  247.  
  248. /*
  249.  * TopHelp: displays the help file.
  250.  */
  251.  
  252. void
  253. TopHelp(widget)
  254.      Widget          widget;
  255. {
  256.   Widget          DoDisplayFile();
  257.   Widget          displayPopup;
  258.  
  259.   XtVaSetValues(widget, XtNsensitive, False, NULL);
  260.   displayPopup = DoDisplayFile(widget, qres.helpFile);
  261.   XtAddCallback(displayPopup, XtNdestroyCallback, SetSensitiveOn, widget);
  262.  
  263.   PositionShell(displayPopup, widget, SHELLPOS_HWFH);
  264.   XtPopup(displayPopup, XtGrabNone);
  265. }
  266.  
  267. void
  268. ExecHangup()
  269. {
  270.   MdmHangup();
  271.   SeyonMessage("Line Disconnected");
  272. }
  273.  
  274. void
  275. DoHangup(widget)
  276.      Widget          widget;
  277. {
  278.   DestroyShell(widget);
  279.   ExecHangup();
  280. }
  281.  
  282. void
  283. HangupConfirm(widget)
  284.      Widget          widget;
  285. {
  286.   Widget          popup,
  287.                   dialog;
  288.  
  289.   ErrorIfBusy()
  290.  
  291.   if (qres.hangupConfirm) {
  292.     popup = AddSimplePopup("hangup", widget);
  293.     dialog = SeAddDialog("dialog", popup);
  294.     
  295.     XawDialogAddButton(dialog, "yes", DoHangup, (XtPointer) dialog);
  296.     XawDialogAddButton(dialog, "cancel", DestroyShell, NULL);
  297.     
  298.     PopupCentered(popup, widget);
  299.   }
  300.   else
  301.     ExecHangup();
  302. }
  303.  
  304. void
  305. ExitNoHangup(widget)
  306.      Widget          widget;
  307. {
  308.   DestroyShell(widget);
  309.   s_exit(widget);
  310. }
  311.  
  312. void
  313. ExitHangup(widget)
  314.      Widget          widget;
  315. {
  316.   ExecHangup();
  317.   ExitNoHangup(widget);
  318. }
  319.  
  320. void
  321. ExitConfirm(widget)
  322.      Widget          widget;
  323. {
  324.   Widget          popup,
  325.                   dialog;
  326.  
  327.   if (qres.exitConfirm && !qres.ignoreModemDCD && Online()) {
  328.     popup = AddSimplePopup("exit", widget);
  329.     dialog = SeAddDialog("dialog", popup);
  330.     
  331.     XawDialogAddButton(dialog, "yes", ExitHangup, NULL);
  332.     XawDialogAddButton(dialog, "no", ExitNoHangup, NULL);
  333.     XawDialogAddButton(dialog, "cancel", DestroyShell, NULL);
  334.     
  335.     PopupCentered(popup, widget);
  336.   }
  337.   else
  338.     s_exit();
  339. }
  340.  
  341. void
  342. ExitAction(widget)
  343.      Widget          widget;
  344. {
  345.   Boolean         wExitButtonStatus;
  346.  
  347.   /* Prevent the user from exiting the program by f.delete if exiting
  348.      is not permitted */
  349.   XtVaGetValues(w_exit, XtNsensitive, &wExitButtonStatus, NULL);
  350.   ReturnIfTrue(!wExitButtonStatus);
  351.   s_exit();
  352. }
  353.  
  354. void
  355. w_exit_up(w_exit_status)
  356.      Boolean         w_exit_status;
  357. {
  358.   XtVaSetValues(w_exit, XtNsensitive, w_exit_status, NULL);
  359. }
  360.  
  361. void
  362. SetKillButtonSens(killWidgetStatus)
  363.      Boolean         killWidgetStatus;
  364. {
  365.   XtVaSetValues(w_kill, XtNsensitive, killWidgetStatus, NULL);
  366.   w_exit_up(!killWidgetStatus);
  367. }
  368.  
  369. void
  370. w_kill_up(w_kill_status)
  371.      Boolean         w_kill_status;
  372. {
  373.   SetKillButtonSens(w_kill_status);
  374. }
  375.  
  376. void
  377. KillChildProc()
  378. {
  379.   if (w_child_pid == 0) return;
  380.   if (kill(w_child_pid, SIGTERM) == 0) w_child_pid = 0;
  381. }
  382.  
  383. void
  384. GetQuickKeyResources(quickKeyName, quickKeyRes)
  385.      String               quickKeyName;
  386.      struct _quickKeyRes *quickKeyRes;
  387. {
  388. #define offset(field) XtOffsetOf(struct _quickKeyRes, field)
  389.   static XtResource resources[] = {
  390.     {"visible", "Visible", XtRBoolean, sizeof(Boolean),
  391.        offset(visible), XtRImmediate, (XtPointer)False},
  392.     {"action", "Action", XtRString, sizeof(String),
  393.        offset(action), XtRString, (XtPointer)""},
  394.   };
  395. #undef offset
  396.   
  397.   XtGetSubresources(topLevel, (XtPointer)quickKeyRes, quickKeyName, "Command",
  398.                     resources, XtNumber(resources), NULL, 0);
  399. }
  400.  
  401. void
  402. GetResources()
  403. {
  404. #define offset(field) XtOffsetOf(struct QueryResources, field)
  405.  
  406.   static XtResource resources[] = {
  407.     {"modems", "Modems", XtRString, sizeof(String),
  408.        offset(modems), XtRString, (XtPointer)""},
  409.     {"script", "Script", XtRString, sizeof(String),
  410.        offset(script), XtRString, (XtPointer) NULL},
  411.     
  412.     {"defaultBPS", "DefaultBPS", XtRString, sizeof(String),
  413.        offset(defaultBPS), XtRString, (XtPointer) "9600"},
  414.     {"defaultBits", "DefaultBits", XtRInt, sizeof(int),
  415.        offset(defaultBits), XtRImmediate, (XtPointer) 8},
  416.     {"defaultParity", "DefaultParity", XtRInt, sizeof(int),
  417.        offset(defaultParity), XtRImmediate, (XtPointer) 0},
  418.     {"defaultStopBits", "DefaultStopBits", XtRInt, sizeof(int),
  419.        offset(defaultStopBits), XtRImmediate, (XtPointer) 1},
  420.     {"stripHighBit", "StripHighBit", XtRBoolean, sizeof(Boolean),
  421.        offset(stripHighBit), XtRImmediate, (XtPointer) False},
  422.     {"backspaceTranslation", "BackspaceTranslation", XtRBoolean,
  423.        sizeof(Boolean), offset(backspaceTranslation), XtRImmediate,
  424.        (XtPointer) False},
  425.     {"metaKeyTranslation", "MetaKeyTranslation", XtRBoolean,
  426.        sizeof(Boolean), offset(metaKeyTranslation), XtRImmediate,
  427.        (XtPointer) True},
  428.     {"xonxoffFlowControl", "XonxoffFlowControl", XtRBoolean,
  429.        sizeof(Boolean), offset(xonxoffFlowControl), XtRImmediate,
  430.        (XtPointer) False},
  431.     {"rtsctsFlowControl", "RtsctsFlowControl", XtRBoolean,
  432.        sizeof(Boolean), offset(rtsctsFlowControl), XtRImmediate,
  433.        (XtPointer) False},
  434.     {"newlineTranslation", "NewlineTranslation", XtRString,
  435.        sizeof(String), offset(newlineTranslation), XtRImmediate,
  436.        (XtPointer) "cr"},
  437.  
  438.     {"dialPrefix", "DialPrefix", XtRString, sizeof(String),
  439.        offset(dialPrefix), XtRString, (XtPointer) "ATDT"},
  440.     {"dialSuffix", "DialSuffix", XtRString, sizeof(String),
  441.        offset(dialSuffix), XtRString, (XtPointer) "^M"},
  442.     {"dialCancelString", "DialCancelString", XtRString, sizeof(String),
  443.        offset(dialCancelString), XtRString, (XtPointer) "^M"},
  444.  
  445.     {"dialTimeOut", "DialTimeOut", XtRInt, sizeof(int),
  446.        offset(dialTimeOut), XtRImmediate, (XtPointer) 45},
  447.     {"dialDelay", "DialDelay", XtRInt, sizeof(int),
  448.        offset(dialDelay), XtRImmediate, (XtPointer) 10},
  449.     {"dialRepeat", "DialRepeat", XtRInt, sizeof(int),
  450.        offset(dialRepeat), XtRImmediate, (XtPointer) 5},
  451.  
  452.     {"connectString", "ConnectString", XtRString, sizeof(String),
  453.        offset(connectString), XtRString, (XtPointer) "CONNECT"},
  454.     {"noConnectString1", "NoConnectString1", XtRString, sizeof(String),
  455.        offset(noConnectString[0]), XtRString, (XtPointer) "NO CARRIER"},
  456.     {"noConnectString2", "NoConnectString2", XtRString, sizeof(String),
  457.        offset(noConnectString[1]), XtRString, (XtPointer) "NO DIALTONE"},
  458.     {"noConnectString3", "NoConnectString3", XtRString, sizeof(String),
  459.        offset(noConnectString[2]), XtRString, (XtPointer) "BUSY"},
  460.     {"noConnectString4", "NoConnectString4", XtRString, sizeof(String),
  461.        offset(noConnectString[3]), XtRString, (XtPointer) "VOICE"},
  462.  
  463.     {"hangupBeforeDial", "HangupBeforeDial", XtRBoolean, sizeof(Boolean),
  464.        offset(hangupBeforeDial), XtRImmediate, (XtPointer)True},
  465.     {"dialAutoStart", "DialAutoStart", XtRBoolean, sizeof(Boolean),
  466.        offset(dialAutoStart), XtRImmediate, (XtPointer)False},
  467.     {"dialDirFormat", "DialDirFormat", XtRString, sizeof(String),
  468.        offset(dialDirFormat), XtRString,
  469.        (XtPointer)"%-15s %-15s %6s %1c%1c%1c %1c%1c %s"},
  470.     {"defaultPhoneEntries", "DefaultPhoneEntries", XtRString, sizeof(String),
  471.        offset(defaultPhoneEntries), XtRString, (XtPointer)NULL},
  472.  
  473.     {"startupAction", "StartupAction", XtRString, sizeof(String),
  474.        offset(startupAction), XtRString, 
  475.        (XtPointer)"RunScript(startup);"},
  476.     {"postConnectAction", "PostConnectAction", XtRString, sizeof(String),
  477.        offset(postConnectAction), XtRString, (XtPointer)"Beep();"},
  478.  
  479.     {"autoZmodem", "AutoZmodem", XtRBoolean, sizeof(Boolean), 
  480.        offset(autoZmodem), XtRImmediate, (XtPointer)True},
  481.     {"autoZmodemAction", "AutoZmodemAction", XtRString, sizeof(String),
  482.        offset(autoZmodemAction), XtRString, 
  483.        (XtPointer)"ShellCommand($rz);"},
  484.  
  485.     {"modemVMin", "ModemVMin", XtRInt, sizeof(int),
  486.        offset(modemVMin), XtRImmediate, (XtPointer) 1},
  487.     {"ignoreModemDCD", "IgnoreModemDCD", XtRBoolean, sizeof(Boolean),
  488.        offset(ignoreModemDCD), XtRImmediate, (XtPointer) False},
  489.     {"hangupViaDTR", "HangupViaDTR", XtRBoolean, sizeof(Boolean),
  490.        offset(hangupViaDTR), XtRImmediate, (XtPointer)False},
  491.     {"modemAttentionString", "ModemAttentionString", XtRString, sizeof(String),
  492.        offset(modemAttentionString), XtRString, (XtPointer)"+++"},
  493.     {"modemHangupString", "ModemHangupString", XtRString, sizeof(String),
  494.        offset(modemHangupString), XtRString, (XtPointer)"ATH^M"},
  495.     {"hangupConfirm", "HangupConfirm", XtRBoolean, sizeof(Boolean),
  496.        offset(hangupConfirm), XtRImmediate, (XtPointer) True},
  497.     {"exitConfirm", "ExitConfirm", XtRBoolean, sizeof(Boolean),
  498.        offset(exitConfirm), XtRImmediate, (XtPointer) True},
  499.  
  500.     {"defaultDirectory", "DefaultDirectory", XtRString, sizeof(String),
  501.        offset(defaultDirectory), XtRString, (XtPointer) "~/.seyon"},
  502.     {"scriptDirectory", "scriptDirectory", XtRString, sizeof(String),
  503.        offset(scriptDirectory), XtRString, (XtPointer) NULL},
  504.     {"startupFile", "StartupFile", XtRString, sizeof(String),
  505.        offset(startupFile), XtRString, (XtPointer) "startup"},
  506.     {"phoneFile", "PhoneFile", XtRString, sizeof(String),
  507.        offset(phoneFile), XtRString, (XtPointer) "phonelist"},
  508.     {"protocolsFile", "ProtocolsFile", XtRString, sizeof(String),
  509.        offset(protocolsFile), XtRString, (XtPointer) "protocols"},
  510.     {"captureFile", "CaptureFile", XtRString, sizeof(String),
  511.        offset(captureFile), XtRString, (XtPointer) "capture"},
  512.     {"helpFile", "HelpFile", XtRString, sizeof(String),
  513.        offset(helpFile), XtRString, (XtPointer) HELPFILE},
  514.  
  515.     {"modemStatusInterval", "ModemStatusInterval", XtRInt, sizeof(int),
  516.        offset(modemStatusInterval), XtRImmediate, (XtPointer) 5},
  517.  
  518.     {"idleGuard", "IdleGuard", XtRBoolean, sizeof(Boolean),
  519.        offset(idleGuard), XtRImmediate, (XtPointer) False},
  520.     {"idleGuardInterval", "IdleGuardInterval", XtRInt, sizeof(int),
  521.        offset(idleGuardInterval), XtRImmediate, (XtPointer) 300},
  522.     {"idleGuardString", "IdleGuardString", XtRString, sizeof(String),
  523.        offset(idleGuardString), XtRImmediate, (XtPointer) " ^H"},
  524.  
  525.     {"showFunMessages", "ShowFunMessages", XtRBoolean, sizeof(Boolean),
  526.        offset(showFunMessages), XtRImmediate, (XtPointer) True},
  527.     {"funMessagesInterval", "FunMessagesInterval", XtRInt, sizeof(int),
  528.        offset(funMessagesInterval), XtRImmediate, (XtPointer) 15},
  529.     {"funMessages", "FunMessages", XtRStringArray, sizeof(String*),
  530.        offset(funMessages), XtRStringArray, (XtPointer) NULL},
  531.   };
  532.  
  533. #undef offset
  534.  
  535.   XtSetTypeConverter(XtRString, XtRStringArray, CvtStringToStringArray,
  536.                      NULL, 0, XtCacheNone, NULL);
  537.  
  538.   XtGetApplicationResources(topLevel, (XtPointer)&qres, resources,
  539.                             XtNumber(resources), NULL, 0);
  540. }
  541.